import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

import org.jdesktop.swingx.JXDatePicker;

import CustomSwing.CTLPanel;
import CustomSwing.JCLabel;
import CustomSwing.JCTextField;

@SuppressWarnings("serial")
public class VendorSalesPanel extends JPanel {
	public final String USER_FUNC = "Vendor Sales";
	private Font custFont = new Font("Arial Bold", Font.BOLD, 15);
	private static String ENTER_BTN = "Enter New Data";
	private static String UPDATE_BTN = "Update (Overwrite) Data";

	private Db db;
	private JPanel resultPanel;
	private JComboBox vidCB;
	private JRadioButton yesRB = new JRadioButton();
	private JRadioButton noRB = new JRadioButton();
	private ButtonGroup paidBG = new ButtonGroup();
	private JXDatePicker datePicker = new JXDatePicker();

	//will return the texts here to the database
	private String vID;
	private String date;
	private JCTextField plantsTF = new JCTextField("0");
	private JCTextField produceTF = new JCTextField("0");
	private JCTextField processorTF = new JCTextField("0");
	private JCTextField prepFoodTF = new JCTextField("0");
	private JCTextField crafterTF = new JCTextField("0");
	private JCTextField resellerTF = new JCTextField("0");
	private JCTextField numStallsTF = new JCTextField("1");
	private boolean paidBool = false; //determines paid
	private JCLabel paid = new JCLabel("");

	private JCLabel totalSales = new JCLabel("");
	private JCLabel marketFee = new JCLabel("");
	private JCLabel stallFee = new JCLabel("");
	private JCLabel totalDue = new JCLabel("");

	public VendorSalesPanel(Db theDB) {
		db = theDB;
		setVIDComboBox();
		setDatePicker();
		addListenersToTFs();
		setRadioButton(yesRB, "YES", paidBool);
		setRadioButton(noRB, "NO", !paidBool);

		JPanel updateDataPanel = new JPanel(new GridLayout(10, 2, 0, 2));
		updateDataPanel.add(new JCLabel("Vendor ID"));
		updateDataPanel.add(vidCB);
		updateDataPanel.add(new JCLabel("Date"));
		updateDataPanel.add(datePicker);
		updateDataPanel.add(new JCLabel("Plants"));
		updateDataPanel.add(plantsTF);
		updateDataPanel.add(new JCLabel("Produce"));
		updateDataPanel.add(produceTF);
		updateDataPanel.add(new JCLabel("Processor"));
		updateDataPanel.add(processorTF);
		updateDataPanel.add(new JCLabel("Prep. Food"));
		updateDataPanel.add(prepFoodTF);
		updateDataPanel.add(new JCLabel("Crafter"));
		updateDataPanel.add(crafterTF);
		updateDataPanel.add(new JCLabel("Reseller")); 
		updateDataPanel.add(resellerTF);
		updateDataPanel.add(new JCLabel("# of Stalls"));
		updateDataPanel.add(numStallsTF);
		updateDataPanel.add(new JCLabel("Paid?"));
		JPanel paidPanel = new JPanel(new GridLayout(1, 2));
		paidPanel.add(yesRB);
		paidPanel.add(noRB);
		updateDataPanel.add(paidPanel);

		resultPanel = new JPanel(new GridLayout(6, 1, 0, 5));
		resultPanel.add(new CTLPanel(totalSales, "Total Sales", 1));
		resultPanel.add(new CTLPanel(marketFee, "Market Fee", 1));
		resultPanel.add(new CTLPanel(stallFee, "Stall Fee", 1));
		resultPanel.add(new CTLPanel(totalDue, "Total Due", 1));
		resultPanel.add(new CTLPanel(paid, "Paid?", 1));
		resultPanel.add(createButton(ENTER_BTN));

		JPanel subMainPanel = new JPanel(new GridLayout(1, 2, 20, 0));
		subMainPanel.add(updateDataPanel);
		subMainPanel.add(resultPanel);

		setLayout(new BorderLayout());
		add(subMainPanel, BorderLayout.CENTER);
		populateFields();
	}

	private void updateInDatabase() {
		try {
			db.updateVendorDailySales(vID, plantsTF.getText(), 
					produceTF.getText(), 
					processorTF.getText(), 
					prepFoodTF.getText(), 
					crafterTF.getText(), 
					resellerTF.getText(), 
					paid.getText(), 
					date,
					numStallsTF.getText(), 
					"1");
			changeButtonTo(UPDATE_BTN);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	private void enterInDatabase() {
		try {
			db.enterVendorDailySales(vID, plantsTF.getText(), 
					produceTF.getText(), 
					processorTF.getText(), 
					prepFoodTF.getText(), 
					crafterTF.getText(), 
					resellerTF.getText(), 
					paid.getText(), 
					date,
					numStallsTF.getText(), 
					"1");
			changeButtonTo(UPDATE_BTN);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	//set values for all fields depending on vID and date.. if it exists in DB.
	private void populateFields() {
		boolean existsInDB = true;
		try {        		
			String[] data = (db.getVendorSales(vID, date));
			plantsTF.setText(data[0]);
			produceTF.setText(data[1]);
			processorTF.setText(data[2]);
			prepFoodTF.setText(data[3]);
			crafterTF.setText(data[4]);
			resellerTF.setText(data[5]);
			numStallsTF.setText(data[6]);
			paidBool = db.paidStatus(vID, date).equalsIgnoreCase("YES") ? true : false;
			yesRB.setSelected(paidBool);
			noRB.setSelected(!paidBool);
			changeButtonTo(UPDATE_BTN);
		} catch (SQLException e) {
			existsInDB = false;
		} catch (ClassNotFoundException e) {
			existsInDB = false;
		} catch (NullPointerException e) {
			existsInDB = false; //assuming no null values
		}
		if (!existsInDB) changeButtonTo(ENTER_BTN);
		
		calculate();
	}

	private boolean calculate() {
		Double stallCost = 0.0;
		Double marketRate = 0.0;
		try {
			stallCost = Double.parseDouble(db.getStallFee("1"));
			marketRate = Double.parseDouble(db.getMarketFee("1"));
		} catch (ClassNotFoundException e1) {
		} catch (SQLException e1) {}

		boolean sucess = true;
		try { 
			DecimalFormat df = new DecimalFormat("0.00");

			Double total = Double.parseDouble(plantsTF.getText()) + 
					Double.parseDouble(produceTF.getText()) +
					Double.parseDouble(processorTF.getText()) +
					Double.parseDouble(prepFoodTF.getText()) +
					Double.parseDouble(crafterTF.getText()) +
					Double.parseDouble(resellerTF.getText());
			Double mFee = total * marketRate;
			Double sFee = Double.parseDouble(numStallsTF.getText()) * stallCost;
			Double tDue = mFee + sFee;

			totalSales.setText(""+df.format(total));
			marketFee.setText(""+df.format(mFee)); 
			stallFee.setText(""+df.format(sFee)); 
			totalDue.setText(""+df.format(tDue));
			if (paidBool) paid.setText("YES"); else paid.setText("NO");
		} 
		catch(NumberFormatException e) {
			sucess = false;
			totalSales.setText("Input numbers only");
			marketFee.setText("Input numbers only");
			stallFee.setText("Input numbers only");
			totalDue.setText("Input numbers only");
			if (paidBool) paid.setText("YES"); else paid.setText("NO");
		}
		return sucess;
	}
	
	private void changeButtonTo(String buttonName) {
		resultPanel.remove(5); //remove enter or update button
		resultPanel.add(createButton(buttonName)); //replace button
		if (buttonName.equals(ENTER_BTN))
			clearAllFields();
		resultPanel.revalidate();
	}

	private JButton createButton(final String name) {
		JButton button = new JButton(name);
		button.setFont(custFont);
		button.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent ae) {
				if (name.equalsIgnoreCase(ENTER_BTN) || 
						name.equalsIgnoreCase(UPDATE_BTN)) {
					if (calculate()) {
						final int value = JOptionPane.showConfirmDialog(null, 
								"Are you sure?", 
								name, JOptionPane.OK_OPTION); 
						if (value == JOptionPane.OK_OPTION) {
							if (name.equalsIgnoreCase(ENTER_BTN))
								enterInDatabase();
							else
								updateInDatabase();
						}
					} else {
						JOptionPane.showConfirmDialog(null, "Input numbers only", 
								"Error", JOptionPane.CLOSED_OPTION); 
					}
				}
			}
		});
		return button;
	}

	private void setVIDComboBox() {
		vidCB = new JComboBox();
		vidCB.setModel(new DefaultComboBoxModel(getVIDStrings()));
		vidCB.setFont(custFont);
		vidCB.setSelectedIndex(0);
		vidCB.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent the_event){
				JComboBox cbEvent = (JComboBox)the_event.getSource();
				vID = (String) cbEvent.getSelectedItem();
				populateFields();
			}
		});
		vID = (String) vidCB.getSelectedItem();
	}
	
	private String[] getVIDStrings() {
		int numAmount = 1;
		try {
			numAmount = db.getVIDs().size();
		} catch (ClassNotFoundException e) {
		} catch (SQLException e) {
		} catch (NullPointerException e) {}
		String[] numbers = new String[numAmount];
		for (int i = 0; i < numAmount; i++)
			numbers[i] = Integer.toString(i+1);
		return numbers;
	}
	
	public void refreshComboBox() {
		vidCB.setModel(new DefaultComboBoxModel(getVIDStrings()));
		vidCB.setSelectedIndex(Integer.parseInt(vID)-1);
	}

	private void setDatePicker() {
		datePicker.setDate(Calendar.getInstance().getTime());
		datePicker.setFormats(new SimpleDateFormat("MM / dd / yyyy"));
		datePicker.getEditor().setEditable(false);
		datePicker.getEditor().setFont(custFont);
		String s = datePicker.getEditor().getText().trim();
		date = s.substring(10, 14) + "-" + s.substring(0, 2) + "-" + s.substring(5, 7);
		datePicker.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent the_event) {
				String s = datePicker.getEditor().getText().trim();
				date = s.substring(10, 14) + "-" + s.substring(0, 2) + "-" + s.substring(5, 7);
				populateFields();
			}
		});
	}

	private void setRadioButton(JRadioButton rb, final String name, boolean initialSelected) {
		rb.setText(name);
		rb.setFont(custFont);
		rb.setSelected(initialSelected);
		rb.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				paidBool = name.equalsIgnoreCase("YES") ? true : false;
				calculate();
			}
		});
		paidBG.add(rb);
	}

	private void addListenersToTFs() {
		addListenersTo(plantsTF);
		addListenersTo(produceTF);
		addListenersTo(processorTF);
		addListenersTo(prepFoodTF);
		addListenersTo(crafterTF);
		addListenersTo(resellerTF);
		addListenersTo(numStallsTF);
	}

	private void addListenersTo(final JCTextField tf) {
		tf.addKeyListener(new KeyAdapter() {
			public void keyReleased(KeyEvent arg0) {
				try {
					if (!Double.isNaN(Double.parseDouble(tf.getText())))
						calculate();
				} catch (NumberFormatException e) {}
			}
		});

		tf.addFocusListener(new FocusListener() {
			public void focusGained(FocusEvent arg0) {
				tf.selectAll();
			}
			public void focusLost(FocusEvent arg0) {
				if (tf.getText().trim().equals(""))
					tf.setText("0");
				calculate();
			}
		});
	}

	private void clearAllFields() {
		paidBool = false;
		yesRB.setSelected(paidBool);
		noRB.setSelected(!paidBool);
		plantsTF.setText("0");
		produceTF.setText("0");
		processorTF.setText("0");
		prepFoodTF.setText("0");
		crafterTF.setText("0");
		resellerTF.setText("0");
		numStallsTF.setText("1");
	}
}
